<template>
  <div class="dk-menu-tree">
    <div class="max-h-300px min-h-200px overflow-auto">
      <div class="flex mb-2">
        <el-button size="small" type="primary" @click="expandAll">展开全部</el-button>
        <el-button size="small" class="ml-2" @click="collapseAll">收起全部</el-button>
      </div>
      <el-tree
        ref="treeRef"
        style="max-width: 600px"
        :data="menuOptions"
        :default-checked-keys="modelValue"
        :default-expanded-keys="halfCheckedIds"
        show-checkbox
        node-key="id"
        :indent="30"
        :default-expand-all="defaultExpandAll"
        :expand-on-click-node="false"
        @check="onRulesCheck"
      >
        <template #default="{ data }">
          <div>
            <el-tag v-if="data.menu_type === 1" size="small">菜单</el-tag>
            <el-tag v-else size="small" type="danger">接口</el-tag>
            <span>{{ data.label }}</span>
          </div>
        </template>
      </el-tree>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { getOption } from '@/api/system/menu'
// 组件名称
defineOptions({
  name: 'DkMenuTree'
})
const emit = defineEmits(['update:modelValue', 'change'])

const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  },
  halfCheckedIds: {
    type: Array,
    default: () => []
  }
})

const menuOptions = ref([])
const treeRef = ref(null)
const defaultExpandAll = ref(true)

// 获取菜单选项
const getMenuOptions = async () => {
  try {
    const res = await getOption()
    menuOptions.value = res.data || []
  } catch (error) {
    console.error('获取菜单选项失败', error)
  }
}

// 处理选择事件
const onRulesCheck = () => {
  const checkedKeys = treeRef.value.getCheckedKeys()
  const halfCheckedKeys = treeRef.value.getHalfCheckedKeys()

  emit('update:modelValue', checkedKeys)
  emit('change', {
    checkedKeys,
    halfCheckedKeys
  })
}

// 展开全部节点
const expandAll = () => {
  if (!treeRef.value) return

  // 优先使用内置的展开方法
  if (typeof treeRef.value.expandAll === 'function') {
    treeRef.value.expandAll()
    return
  }

  // 手动展开所有节点
  const expandNodes = (data) => {
    data.forEach((item) => {
      const node = treeRef.value.getNode(item.id)
      if (node) node.expand()

      if (item.children && item.children.length) {
        expandNodes(item.children)
      }
    })
  }

  expandNodes(menuOptions.value)
}

// 收起全部节点
const collapseAll = () => {
  if (!treeRef.value) return

  // 优先使用内置的折叠方法
  if (typeof treeRef.value.collapseAll === 'function') {
    treeRef.value.collapseAll()
    return
  }

  // 使用Element Plus的内部API重置展开状态
  if (treeRef.value.store && treeRef.value.store.root) {
    // 先将默认展开状态关闭
    defaultExpandAll.value = false

    // 收起所有节点
    const collapseNodes = (node) => {
      if (node.childNodes && node.childNodes.length) {
        node.childNodes.forEach((child) => {
          child.expanded = false
          collapseNodes(child)
        })
      }
    }

    // 从根节点开始收起
    if (treeRef.value.store.root.childNodes) {
      treeRef.value.store.root.childNodes.forEach((rootNode) => {
        // 如果是顶级节点，也折叠它
        rootNode.expanded = false

        // 递归折叠所有子节点
        collapseNodes(rootNode)
      })
    }

    // 强制更新视图
    treeRef.value.$forceUpdate && treeRef.value.$forceUpdate()
  }
}

// 监听 modelValue 变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (treeRef.value && newVal) {
      treeRef.value.setCheckedKeys(newVal)
    }
  },
  { deep: true }
)

onMounted(() => {
  getMenuOptions()
})
</script>

<style>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.dk-menu-tree {
  padding: 15px;
  border: 1px solid var(--el-border-color);
  border-radius: 8px;
}
</style>
